详解Vue中的插槽用法:默认插槽、具名插槽、作用域插槽 | 您所在的位置:网站首页 › element中el-select filterable › 详解Vue中的插槽用法:默认插槽、具名插槽、作用域插槽 |
作者: 小土豆 博客园:www.cnblogs.com/HouJiao/ 掘金:juejin.im/user/243617… 什么是插槽在日常的项目开发中,当我们在编写一个完整的组件时,不可避免的会引用一些外部组件或者自定义组件。 有了这种引用关系之后,我们就可以把它们称为父组件或者子组件,同时父子组件之间有很多的通信方式,比如可以通过props向子组件传递数据,或者通过$emit、$parent调用父组件中的方法。 下面就是一个非常简单的父组件引用子组件的例子。 Badge 标记 评论 进度条 复制代码接着我们在App组件中引用Child组件。 import Child from './components/Child.vue' export default { name: 'App', components: { Child } } 复制代码最后运行项目,子组件的内容成功被引用并展示在页面上。 那假如我们现在有这样一个需求:在引用Child组件的同时,希望在Child组件的指定位置插入一段内容: 欢迎大家关注小土豆 。 如果我们直接将内容写入内部,是不会生效的。 欢迎大家关注小土豆 import Child from './components/Child.vue' export default { name: 'App', components: { Child } } 复制代码可以看到并未达到预期效果: 那为了解决类似这样的问题,Vue就设计出来了slot这个东西。slot翻译过来叫做插槽,也可称其为Vue的内容分发机制,它的主要作用就是向子组件的指定位置插入一段内容,这个内容可以是HTML或者其他的组件。 默认插槽在前面一节内容里,我们提出了一个需求:在引用Child组件的同时,希望在Child组件的指定位置插入一段内容: 欢迎大家关注小土豆 。 那这个需求如何使用插槽来实现呢?我们来实践一下。 首先我们需要在子组件中写入,同时这个在标签内部可以有默认的内容,比如我是这个slot里面本来的内容 Badge 标记 评论 进度条 我是这个slot里面本来的内容 复制代码接着就是在父组件中传入我们希望插入到子组件中的内容。 欢迎大家关注小土豆 import Child from './components/Child.vue' export default { name: 'App', components: { Child } } 复制代码此时在运行项目,就能看到 欢迎大家关注小土豆 这段内容已经成功的显示在页面上。 具名插槽就是给我们的插槽起一个名字,即给定义一个name属性。 复制代码给插槽起了名称以后,我们在父组件中就可以使用v-slot:name或者#name往指定的插槽填充内容。 #name 是v-slot:name的简写形式 下面我们就来实践一下具名插槽。 首先是在子组件(Child.vue)中定义具名插槽。 Badge 标记 评论 进度条 复制代码接着在父组件(App.vue)中使用。 element-ui组件 这里是element-ui的部分组件介绍 出品@小土豆 import Child from './components/Child.vue' export default { name: 'App', components: { Child } } 复制代码运行项目就能看到对应的内容被插入到对应的插槽内: 其实关于前面的默认插槽它也是有name属性的,其值为default,所以在父组件中也可以这样写: 欢迎大家关注小土豆 复制代码 补充内容—— 元素上使用 v-slot 指令在演示具名插槽的时候,我们的v-slot是写在元素上的,这个是比较推荐的写法,因为在处理的过程中不会渲染成真实的DOM节点。 欢迎关注小土豆 复制代码处理之后的DOM节点: 欢迎关注小土豆 复制代码当然我们也可以将v-slot应用在其他的HTML元素上,这样最终插入到子组件中的内容就会有一层真实的DOM节点包裹。 欢迎关注小土豆 复制代码处理之后的DOM节点: 欢迎关注小土豆 复制代码 作用域插槽关于作用域插槽的相关概念和示例看了很多,但相对于前面两种类型的插槽来说,确实有些难以理解。如果需要用一句话去总结作用域插槽,那就是在父组件中访问子组件的数据,或者从数据流向的角度来讲就是将子组件的数据传递到父组件。 一个新概念或者一个新技术的出现总是有原因的,那作用域插槽的出现又是为了解决什么样的问题呢?一起来研究一下吧。 作用域插槽的使用我们先来看看如何利用作用域插槽实现在父组件中访问子组件的数据。 首先我们需要在子组件的插槽上使用v-bind绑定对应的数据。 {{heading}} export default { name: 'Child', data() { return { heading: '这里是默认的heading' } } } 复制代码可以看到我们在上使用v-bind绑定了vue data中定义的heading数据。 接着我们就可以在父组件中定义一个变量来接收子组件中传递的数据。 父组件中接收数据的变量名可以随意起,这里我起的变量名为slotValue element-ui组件 slotValue = {{slotValue}} 复制代码运行项目后查看页面的结果: 可以看到slotValue是一个对象,保存了一组数据,其键就是我们在子组件的上使用v-bind绑定的属性名headingValue,其值是v-bind绑定的heading值。 前面我们了解了作用域插槽的用法,也得知其主要目的是为了能在父组件中访问子组件的数据。那什么时候父组件需要访问子组件的数据呢。 我们来举个简单的栗子。 假设我们有下面这样一个Card组件: {{title}} {{item.id}}.{{item.text}} export default { name: 'Card', props: ['title', 'list'], data() { return { } } } .list{ border: 1px solid; padding: 20px; } .list p{ border-bottom: 2px solid #fff; padding-bottom: 5px; } 复制代码其中Card组件中展示的title和list数据由父组件传入。 接着在App组件中复用Card组件,并且传入title和list数据。 import Card from './components/Card.vue' export default { name: 'App', components: { Card, }, data() { return { title: '名人名言', list:[ { id:1, text:'要成功,先发疯,头脑简单向前冲' },{ id:2, text:'不能天生丽质就只能天生励志!' },{ id:3, text:'世上唯一不能复制的是时间,唯一不能重演的是人生。' } ] } } } #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; /* text-align: center; */ /* color: #2c3e50; */ /* margin-top: 60px; */ color: #fff; background: rgba(232, 0, 0, 0.3); padding: 20px; } 复制代码运行项目查看页面: Card组件本身并不复杂,就是展示title和list里面的数据。但凡是有相同需求的都可以通过复用Card组件来实现。 但是仔细去想,我们的Card组件其实并没有那么灵活:如果有些页面需要复用该组件,但是希望在title处增加一个图标;或者有些页面需要在展示内容时候不显示编号1、2、3。 那这样的需求使用插槽就可以轻松实现。 {{title}} {{item.id}}.{{item.text}} 复制代码我们在Card组件展示title和list的位置分别添加了对应的具名插槽,并且通过v-bind将title、item(list循环出来的数据)传递给了父组件。 此时父组件就可以控制子组件的显示。 假如我们需要在title处添加图标,则App组件复用Card组件的方式如下: {{slotTitle.titleValue}} 复制代码页面效果: 亦或者有些页面需要在展示内容时候不显示编号1、2、3: {{slotItem.itemValue.text}} 复制代码页面效果: 这里应该能想起来element table组件的实现方式,是不是也有点这样的意思呢 到这里或许有人会说这样的需求不用插槽也能实现,直接在Card组件中增加一些逻辑即可。这样的说法固然是可以实现功能,但是显然不是一个好办法。 因为组件的设计本身是希望拿来复用的,如果这个组件本身大部分实现是符合我们的需求的,只有一小部分不符合,我们首先应该想要的是去扩展该组件,而不是修改组件,这也是软件设计的思想:开放扩展,关闭修改。所以插槽的出现正是对组件的一种扩展,让我们可以更加灵活的复用组件。 废弃的插槽语法关于以上所描述的插槽语法,均是vue 2.6.0以后的语法。在这之前,插槽的语法为slot(默认插槽或者具名插槽)和slot-scope(作用域插槽)。 默认插槽 欢迎关注小土豆 或者 欢迎关注小土豆 复制代码页面效果: 页面效果: 页面效果: 到这里本篇文章就结束了,内容非常简单易懂,可以是茶余饭后的一篇知识回顾。 最后我们在来做一个小小的总结: 如果这篇文章有帮助到你,❤️关注+点赞❤️鼓励一下作者 笔芯❤️~ 作者: 小土豆 博客园:www.cnblogs.com/HouJiao/ 掘金:juejin.im/user/243617… |
CopyRight 2018-2019 实验室设备网 版权所有 |